<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket通讯</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<!--
//实现化WebSocket对象，指定要连接的服务器地址与端口  建立连接
            //等同于socket = new WebSocket("socket://localhost:8888/xxxx/im/25");
            //var socketUrl="${request.contextPath}/im/"+$("#userId").val();

-->
<script>

    $(document).ready(function () {
        lockReconnect = false;  //避免ws重复连接
        socket = null;
        socketUrl = "http://localhost:8080/" + $("#userId").val() + "/1";
        socketUrl = socketUrl.replace("https", "wss").replace("http", "ws");
    });

    function createWebSocket(url) {
        try {
            if (typeof (WebSocket) == "undefined" && !('WebSocket' in window)) {
                console.log("您的浏览器不支持WebSocket");
            } else {
                console.log("连接对象：" + url);
                if (socket != null) {
                    socket.close();
                    socket = null;
                }
                socket = new WebSocket(url);

                initEventHandle();
            }
        } catch (e) {
            reconnect(url);
            console.log(e);
        }

    }


    /*
    * websocket生命周期
    * */
    function initEventHandle() {
        socket.onclose = function () {
            reconnect(socketUrl);
            console.log("llsocket连接关闭!" + new Date().toLocaleString());
        };
        socket.onerror = function () {
            reconnect(socketUrl);
            console.log("llsocket连接错误!");
        };
        socket.onopen = function () {
            heartCheck.reset().start();      //心跳检测重置
            console.log("llsocket连接成功!" + new Date().toLocaleString());
        };
        socket.onmessage = function (event) {    //如果获取到消息，心跳检测重置
            heartCheck.reset().start();      //拿到任何消息都说明当前连接是正常的
            console.log("llsocket收到消息啦:" + event.data);
            if (event.data != 'pong' && typeof (event.data) == "undefined") {
                let data = JSON.parse(event.data);
                console.log("data" + data);
            }
        };
    }

    // 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
    window.onbeforeunload = function () {
        socket.close();
    }

    function reconnect(url) {
        if (lockReconnect) return;
        lockReconnect = true;
        setTimeout(function () {     //没连接上会一直重连，设置延迟避免请求过多
            createWebSocket(url);
            lockReconnect = false;
        }, 2000);
    }

    //心跳检测
    var heartCheck = {
        timeout: 1000 * 60,        //1分钟发一次心跳
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function () {
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function () {
            var self = this;
            this.timeoutObj = setTimeout(function () {
                //这里发送一个心跳，后端收到后，返回一个心跳消息，
                //onmessage拿到返回的心跳就说明连接正常
                socket.send("ping");
                console.log("ping!");
                self.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置，说明后端主动断开了
                    socket.close();     //如果onclose会执行reconnect，我们执行socket.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                }, self.timeout)
            }, this.timeout)
        }
    }

    function sendMessage() {
        if (typeof (WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        } else {
            console.log("您的浏览器支持WebSocket");
            console.log('{"toUserId":"' + $("#toUserId").val() + '","contentText":' + $("#contentText").val() + '}');
            socket.send('{"toUserId":"' + $("#toUserId").val() + '","contentText":' + $("#contentText").val() + '}');
        }
    }
</script>
<body>
<p>【userId】：
<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【toUserId】：
<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
<p>【toUserId】：
<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>【操作】：
<div><a onclick="createWebSocket(socketUrl)">开启socket</a></div>
<p>【操作】：
<div><a onclick="sendMessage()">发送消息</a></div>
</body>

</html>
